#include "TListaPlacaMux.h"

void TLPM_Crear(TListaPlacaMux *lista, int tam_elemento){
  lista->corriente = NULL;
	lista->primero = NULL;
	lista->tam_elemento = tam_elemento;
}

void TLPM_Destruir(TListaPlacaMux *lista) {
	TNodoListaPlacaMux *nodo, *siguiente;
	TElementoListaPlacaMux *elemento;

	for (nodo = lista->primero; nodo; nodo = siguiente) {
		siguiente = nodo->siguiente;
		elemento = (TElementoListaPlacaMux*) nodo->elemento;
		Mux_Destruir(elemento->mux);
		Placa_Destruir(elemento->placa);
		free(elemento->mux);
		free(elemento->placa);
	}
}

void TLPM_Vaciar(TListaPlacaMux *lista){
	TNodoListaPlacaMux *nodo, *siguiente;

	for (nodo = lista->primero; nodo; nodo = siguiente) {
		siguiente = nodo->siguiente;
		free(nodo->elemento);
		free(nodo);
	}

	lista->primero = lista->corriente = NULL;
}

int TLPM_Vacia(TListaPlacaMux *lista){
    return (lista->primero == NULL);
}

int TLPM_InsertarElemento(TListaPlacaMux *lista, void *elemento){
    TNodoListaPlacaMux* nodo;

    nodo = (TNodoListaPlacaMux*) malloc(sizeof(TNodoListaPlacaMux));

    if (!nodo) {
        return TLPM_ERR_MEMORIA;
    }

    (nodo->elemento) = malloc(lista->tam_elemento);

    if (!(nodo->elemento)){
        free(nodo);
        return TLPM_ERR_MEMORIA;
    }

    memcpy(nodo->elemento,elemento,lista->tam_elemento);
    nodo->siguiente = NULL;

    if (TLPM_Vacia(lista)) {
        lista->primero = nodo;
        lista->corriente = nodo;
        return TLPM_OK;
    }
    else {
        lista->corriente = lista->primero;
        while (lista->corriente->siguiente) {
            lista->corriente = lista->corriente->siguiente;
        }

        lista->corriente->siguiente = nodo;
        lista->corriente = nodo;
        return TLPM_OK;
    }
}

void TLPM_ElementoCorriente(TListaPlacaMux *lista, void *elemento){
    memcpy(elemento, lista->corriente->elemento, lista->tam_elemento);
}

int TLPM_MoverCorriente(TListaPlacaMux *lista, TMovimiento movimiento){
    if (TLPM_Vacia(lista)) {
		return TLPM_ERR_LISTAVACIA;
	}
    else {
		switch (movimiento) {
			case LS_PRIMERO:
				lista->corriente = lista->primero;
				break;

			case LS_SIGUIENTE:
				if (lista->corriente->siguiente == NULL) {
					return TLPM_ERR_NOHAYSIGUIENTE;
				}
				else {
					lista->corriente = lista->corriente->siguiente;
				}
                    break;

			case LS_ANTERIOR:
				return TLPM_ERR_NOIMPLEMENTADO;
			default:
				return TLPM_ERR_NOIMPLEMENTADO;
		}

    	return TLPM_OK;
    }
    return TLPM_OK;
}

int TLPM_BorrarCorriente(TListaPlacaMux *lista){
    TNodoListaPlacaMux* nodo;

	nodo = lista->corriente;

	if (TLPM_Vacia(lista)) {
		return TLPM_ERR_LISTAVACIA;
	}

	if (lista->corriente == lista->primero) {
		lista->primero = lista->corriente->siguiente;
		lista->corriente = lista->primero;
    }
    else {
		TNodoListaPlacaMux* nodo_aux = lista->primero;

		while (nodo_aux->siguiente != lista->corriente) {
			nodo_aux = nodo_aux->siguiente;
		}

		nodo_aux->siguiente = lista->corriente->siguiente;
		if (nodo_aux->siguiente) {
			lista->corriente = nodo_aux->siguiente;
		}
		else {
			lista->corriente = nodo_aux;
		}
	}

    free(nodo->elemento);
    free(nodo);

    return TLPM_OK;
}

void TLPM_ModificarCorriente(TListaPlacaMux *lista, void *elemento){
    memcpy(lista->corriente->elemento, elemento, lista->tam_elemento);
}
